package api

import (
	"api/config"
	"api/config/code"
	"api/libs/errs"
	"api/libs/orm"
	"context"
	"encoding/json"
	"gitee.com/dreamwood/ez"
	"gitee.com/dreamwood/ez/server"
	"net/http"
)

type MyOperation struct {
	Operation *server.Operation
	HttpQuery *orm.HttpQuery
}

func (this *MyOperation) Get(key string) *server.InputAnyThing {
	return this.Operation.Input.Get(key)
}

func (this *MyOperation) GetHeader() http.Header {
	return this.Operation.Input.Request.Header
}

func (this *MyOperation) SetHeader(key string, value string) {
	this.Operation.Input.Request.Header.Set(key, value)
}

func (this *MyOperation) CreateContext() context.Context {
	return context.WithValue(context.Background(), "MyOperation", this)
}

func (this *MyOperation) GetAuthToken() string {
	return this.Operation.GetHeader().Get(config.GetApi().AuthTokenName)
}

func (this *MyOperation) FillJson(model interface{}) error {
	return json.Unmarshal(this.Operation.Input.Json, model)
}

func (this *MyOperation) CheckError(err error) bool {
	if err != nil {
		data := NewJsonOut(code.ErrorServer, errs.Get(err))
		this.Operation.Output.Json(data)
		return true
	}
	return false
}

// 如果不好理解就使用这个别名
func (this *MyOperation) HasError(err error) bool { return this.CheckError(err) }

// Try 检查是否有错误，如果有则返回true,没有错误返回false,本质上还是CheckError
// ***********************************
//
//	典型应用：
//	if this.TryTo( err ) {
//			return
//	}
//
// ***********************************
func (this *MyOperation) Try(err error) bool { return this.CheckError(err) }

func (this *MyOperation) JsonOut(data interface{}) {
	this.Operation.Output.Json(data)
}
func (this *MyOperation) Html(data string) {
	this.Operation.Output.Html(data)
}

func (this *MyOperation) ReturnSuccess(message string, data interface{}) {
	jsonData := make(map[string]interface{})
	jsonData["code"] = code.Success
	jsonData["message"] = message
	jsonData["data"] = data
	this.JsonOut(jsonData)
}

func (this *MyOperation) ReturnError(code int, message string, data interface{}) {
	jsonData := make(map[string]interface{})
	jsonData["code"] = code
	jsonData["message"] = message
	jsonData["data"] = data
	this.JsonOut(jsonData)
}

func (this *MyOperation) Stop() {
	this.Operation.IsStop = true
}

// Handler
func (this *MyOperation) StopHandle() {
	this.Operation.Handler.IsStop = true
}
func (this *MyOperation) SetPublic(dataName string, data interface{}) {
	this.Operation.Handler.Set(dataName, data)
}
func (this *MyOperation) GetPublic(dataName string) interface{} {
	return this.Operation.Handler.Get(dataName)
}

// Logger
func (this *MyOperation) Logout(format string, v ...interface{}) {
	if ez.GetDebug() {
		this.Operation.Logger.Printf(format, v...)
	}
}
func (this *MyOperation) Debug(format string, v ...interface{}) {
	if ez.GetDebug() {
		this.Operation.Logger.Printf(format, v...)
	}
}

type JsonOut struct {
	Code    int         `json:"code"`
	Message string      `json:"message"`
	Data    interface{} `json:"data"`
}

func NewJsonOut(p ...interface{}) *JsonOut {
	jsonOut := new(JsonOut)
	if len(p) > 0 {
		jsonOut.Code = p[0].(int)
	}
	if len(p) > 1 {
		jsonOut.Message = p[1].(string)
	}
	if len(p) > 2 {
		jsonOut.Data = p[2]
	}
	return jsonOut
}

func (this *MyOperation) GetHttpQuery() *MyOperation {
	query := orm.NewHttpQuery()
	if errs.Try(this.FillJson(query)) {
		this.HttpQuery = query
		return this
	}
	this.HttpQuery = query
	return this
}
